package com.lemi.util;

import java.util.UUID;

/**
 * @author kevin
 * @since 2020/4/22 1:39 PM
 */
public class IdGenUtils {
    private static final String toBase64URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

    private IdGenUtils() {
    }

    public static String uuid() {
        UUID uuid = UUID.randomUUID();
        return base64Encode(uuid);
    }

    public static String base64Encode(UUID uuid) {
        char[] chs = new char[22];
        long most = uuid.getMostSignificantBits();
        long least = uuid.getLeastSignificantBits();
        int k = chs.length - 1;

        int i;
        for(i = 0; i < 10; least >>>= 6) {
            chs[k--] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt((int)(least & 63L));
            ++i;
        }

        chs[k--] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt((int)(least & 63L | (most & 3L) << 4));
        most >>>= 2;

        for(i = 0; i < 10; most >>>= 6) {
            chs[k--] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt((int)(most & 63L));
            ++i;
        }

        chs[k] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".charAt((int)most);
        return new String(chs);
    }

    public static String base64Encode(String uuidStr) {
        StringBuilder sb = new StringBuilder(uuidStr);
        sb.insert(20, '-');
        sb.insert(16, '-');
        sb.insert(12, '-');
        sb.insert(8, '-');
        UUID uuid = UUID.fromString(sb.toString());
        return base64Encode(uuid);
    }

    public static String base64Decode(String base64) {
        StringBuilder sb = new StringBuilder();

        for(int i = base64.length(); i > 0; i -= 2) {
            int c1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(String.valueOf(base64.charAt(i - 1)));
            int c2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".indexOf(String.valueOf(base64.charAt(i - 2)));
            sb.insert(0, Integer.toHexString(c1 & 15));
            sb.insert(0, Integer.toHexString(c1 >>> 4 & 3 | c2 << 2 & 12));
            if (i != 2) {
                sb.insert(0, Integer.toHexString(c2 >>> 2 & 15));
            }
        }

        return sb.toString();
    }
}
